package com.lsk.api;


import com.jfinal.kit.HttpKit;
import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Record;
import com.jfinal.plugin.redis.Cache;
import com.jfinal.plugin.redis.Redis;
import com.lsk.util.*;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.eclipse.jetty.util.UrlEncoded;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.Charset;
import java.security.MessageDigest;
import java.util.*;

/**
 * 收卡啦
 */
public class SKService {

    public static String userCode = "17280184950";//userCode

    public static String cardSubmitUrl = "http://api.shoukala.com:8088/apply/card";

    public static String appkey = "2ace777d15e7c27bcd38d5e1ba82e11d";


    static Cache cache = Redis.use();

    /**
     * 卡id
     *
     * @param record
     */
    public static void cardSubmit(Record record) {

        String cacheCardId = record.getStr("id");

        String id = record.getStr("commodityId");
        /*查询收卡啦卡信息*/
        String sql = "SELECT *from sk_commodity where commodityId='" + id + "'";

        Record sk = Db.findFirst(sql);

        try {

            String confiSql = "SELECT `value` from sys_config where element='domain'";

            String domain = Db.queryStr(confiSql);

            Map<String, String> parameters = new HashMap<>();

            parameters.put("userCode", userCode);


            /**根据cardId获取 commodity_facevalue skid**/
            String skCommodityId = Db.queryStr("select skCommodityId from commodity_facevalue where id = (select feedbackId from card where id =?)", cacheCardId);

            if (skCommodityId == null || "".equals(skCommodityId)) {
                Syslog.info("商品" + id + "未设置收卡啦关联商品");
                return;
            }

            parameters.put("productId", skCommodityId);

            String cardNo = record.getStr("cardNumber");

            if ("".equals(cardNo) || cardNo==null){
                Syslog.info("无卡号卡种");
            }else {
                parameters.put("cardNo", cardNo);
            }

            String cardPwd = record.getStr("cardPassword");

            parameters.put("cardPwd", encrypt(cardPwd));//卡密

            String dateTime = DateUtil.getSdfTimes();

            parameters.put("dateTime", dateTime);

            String retUrl = "http://" + domain.replace("http://", "") + "/mobile/skCallback";

            parameters.put("retUrl", UtilUrlEncode.URLDecoderString(retUrl));

            String userOrderNo = "SK" + DateUtil.getSdfTimes() + Tools.getRandomNum();

            parameters.put("userOrderNo", userOrderNo);

            String sign = sign(userCode, skCommodityId, cardPwd, dateTime,
                    cardNo, retUrl, userOrderNo, appkey);

            parameters.put("sign", sign);

            String result = HttpKit.post(cardSubmitUrl, parameters, JsonUtil.getJsonStr(parameters));

            Syslog.info("收卡网网址" + parameters);    //打印收卡网参数
            System.out.println(result);
            Syslog.info("收卡网返回结果" + result);

            Map<String, Object> resultMap = new HashMap<>();

            resultMap = JsonUtil.getMapFromJsonObjStr(result);
            /**
             * 状态码
             */
            String code = resultMap.get("code").toString();
            String SkreturnMsg=ApiReturn.getMsgByCode(code, "3");
            /**如果返回消息,则使用返回消息*/
            if(resultMap.get("message")!=null){
                SkreturnMsg=resultMap.get("message").toString();
            }

            String afterSubmitCardState ="";
            if(code.equals("200")){
                afterSubmitCardState="2";// 推送成功
            }else{
                afterSubmitCardState="3";//推送失败,将不再回调

            }

            String cardId = record.getStr("id");
            Db.update("update card set state=?,msg=? where id =?",afterSubmitCardState,SkreturnMsg+"(收卡啦)",cardId);


            record.remove("code").set("createTime", new Date()).set("returnJson", result)
                    .remove("id").set("cardId", cardId).set("id", userOrderNo);

            Record myData = new Record().set("id", userOrderNo).set("cardId", cardId).set("classId", record.getStr("classId")
            ).set("commodityId", record.getStr("commodityId")).set("commodityName", record.getStr("commodityName"))
                    .set("feedbackId", record.getStr("feedbackId")).set("feedbackValue", record.getStr("feedbackValue"))
                    .set("discount", record.getStr("discount")).set("createTime", new Date()).set("returnCode", resultMap.get("code"))
                    .set("returnMsg", resultMap.get("message"))
                    .set("returnJson", result).set("cardNumber", record.getStr("cardNumber")).set("cardPassword", record.getStr("cardPassword"))
                    .set("orderId", record.getStr("orderId")).set("memberId", record.getStr("memberId")).set("imgPath", record.getStr("imgPath"))
                    .set("className", record.getStr("className"));

            Db.save("card_send_logs", "id", myData);

            Syslog.info("推送收卡啦平台结束，返回结果为：" + result);

            cache.setex("card_send_logs" + cacheCardId, 1800, myData);

        } catch (Exception e) {

            Syslog.error(e);

        }

    }

    /**
     * 加密
     *
     * @param data
     * @return
     */
    public static String encrypt(String data) throws Exception {

        System.out.println("加密前数据为》" + data);

        String key = "shoukala.1234~~!";
        String iv = MD5_16(key);//加密向量
        Cipher cipher = Cipher.getInstance("AES/CBC/NOPadding");
        int blockSize = cipher.getBlockSize();

        byte[] dataBytes = data.getBytes();
        int plaintextLength = dataBytes.length;
        if (plaintextLength % blockSize != 0) {
            plaintextLength = plaintextLength + (blockSize - (plaintextLength % blockSize));
        }

        byte[] plaintext = new byte[plaintextLength];
        System.arraycopy(dataBytes, 0, plaintext, 0, dataBytes.length);

        SecretKeySpec keySpec = new SecretKeySpec(key.getBytes(), "AES");
        IvParameterSpec ivSpec = new IvParameterSpec(iv.getBytes());

        cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);
        byte[] encrypted = cipher.doFinal(plaintext);

        String s = new String(Base64.getEncoder().encode(encrypted));

        System.out.println("加密后数据为   " + s);

        //System.out.println(s);
        return s;
    }

    /**
     * 签名
     *
     * @param userCode
     * @param productId
     * @param cardPwd
     * @param dateTime
     * @param cardNo
     * @param retUrl
     * @param userOrderNo
     * @param appkey
     * @return
     */
    public static String sign(String userCode, String productId, String cardPwd, String dateTime,
                              String cardNo, String retUrl, String userOrderNo, String appkey) {
        String sign = "";
        try {
            sign = userCode + productId + encrypt(cardPwd) + dateTime
                    + cardNo + retUrl + userOrderNo + appkey;
            sign = MD5(sign);
        } catch (Exception e) {
            e.printStackTrace();

        }

        return sign;

    }


    /**
     * @param strings
     */

    public static void main(String[] strings) {

        try {

            cardSubmit(new Record());

        } catch (Exception e) {
            e.printStackTrace();
        }


    }

    /**
     * post请求
     */
    public static String HttpClientPostByJson(String url, String param) {

        //创建client和post对象
        HttpClient client = HttpClients.createDefault();
        HttpPost post = new HttpPost(url);
        //json形式
        post.addHeader("content-type", "application/json;charset=utf-8");
        post.addHeader("accept", "application/json");
        //json字符串以实体的实行放到post中
        post.setEntity(new StringEntity(param, Charset.forName("utf-8")));
        HttpResponse response = null;
        try {
            //获得response对象
            response = client.execute(post);
        } catch (Exception e) {
            e.printStackTrace();
        }

        if (HttpStatus.SC_OK != response.getStatusLine().getStatusCode()) {
            System.out.println("请求返回不正确");
        }

        String result = "";
        try {
            //获得字符串形式的结果
            result = EntityUtils.toString(response.getEntity());
        } catch (Exception e) {
            e.printStackTrace();
        }
        System.out.println(result);
        return result;
    }


    private static final char[] hexDigits = "0123456789abcdef".toCharArray();

    public static String MD5_16(String s) throws Exception {
        return MD5(s).substring(8, 24);
    }

    public static String MD5(String src) throws Exception {
        final byte[] bytes = src.getBytes();
        MessageDigest messageDigest = MessageDigest.getInstance("MD5");
        messageDigest.update(bytes);
        byte[] digestBytes = messageDigest.digest();
        char[] chars = new char[digestBytes.length * 2];
        int k = 0;
        for (byte b : digestBytes) {
            chars[k++] = hexDigits[b >>> 4 & 15];
            chars[k++] = hexDigits[b & 15];
        }
        return new String(chars);
    }


}
